package weworkgo

import (
	"gitee.com/microrain/weworkgo/lib"
	"github.com/gogf/gf/frame/g"
	"github.com/gogf/gf/os/gcache"
	"github.com/gogf/gf/os/glog"
	"time"
)

/**
GetProviderToken 服务商的token
以corpid（服务商CorpID）、provider_secret（服务商密钥）换取provider_access_token，代表的是服务商的身份
用于服务商级别的接口调用，比如登录授权、推广二维码等。说明文档参考 获取服务商凭证
https://work.weixin.qq.com/api/doc/90002/90151/90648
*/
var getProviderTokenURL = "https://qyapi.weixin.qq.com/cgi-bin/service/get_provider_token"

func (p *Provider) GetProviderToken() string {

	corpid := p.Config.CorpId

	providerAccessToken, err := gcache.Get(ProviderAccessTokenCacheKey + corpid)
	if providerAccessToken != nil {
		glog.Info("从缓存中取provider_access_token =========", providerAccessToken)
		ptr := providerAccessToken.(*ProviderTokenResponse)
		return ptr.ProviderAccessToken
	}

	var resData = g.Map{
		"corpid":          p.Config.CorpId,
		"provider_secret": p.Config.Secret,
	}
	result, err := lib.HttpPostData(getProviderTokenURL, resData)

	glog.Debugf("Request GetProviderToken Response:CorpId(%s) %s", corpid, result)
	if err != nil {
		glog.Error(err)
		return ""
	}
	response := lib.UnJson(result, new(ProviderTokenResponse)).(*ProviderTokenResponse)
	if response == nil {
		return ""
	}

	glog.Info("从腾讯服务器远程获取provider_access_token =========", response)
	gcache.SetIfNotExist(ProviderAccessTokenCacheKey+corpid, response, time.Duration(response.ExpiresIn-1000)*time.Second)

	return response.ProviderAccessToken
}

/**
GetCorpTpAuthToken 授权企业的token
企业安装第三方应用后，第三方服务商以企业的corpid、永久授权码来获取access_token	用于操作授权企业相关接口，如通讯录管理，消息推送等。说明文档参考 获取企业凭证
说明：https://work.weixin.qq.com/api/doc/90001/90143/90605
*/
var wechatCorpTpAuthTokenURL = "https://qyapi.weixin.qq.com/cgi-bin/service/get_corp_token?suite_access_token="

func (p *Provider) GetCorpTpAuthToken(corpId string) (string, error) {

	CorpAccessTokenCache, err := gcache.Get(CorpAccessTokenCacheKey + corpId)
	if CorpAccessTokenCache != nil {
		glog.Info("从缓存中取CorpAccessToken =========", CorpAccessTokenCache)
		return CorpAccessTokenCache.(*WechatCorpTpAuthTokenResponse).AccessToken, nil
	}

	//从缓存在获取永久授权码
	permanentCode := p.GetPermanentCode(PermanentCodeCacheKey + p.Config.SuiteId + "_" + corpId)

	//从缓存在获取企业微信第三方应用suite_access_token
	suiteAccessTokenData, err := gcache.Get(SuiteAccessTokenCacheKey + p.Config.SuiteId) //企业微信第三方应用suite_access_token
	if err != nil {
		glog.Error(err)
		return "", err
	}
	sat := suiteAccessTokenData.(*SuiteTokenRespons)

	data := map[string]string{
		"auth_corpid":    corpId,
		"permanent_code": permanentCode}
	result, err := lib.HttpPostData(wechatCorpTpAuthTokenURL+sat.SuiteAccessToken, data)

	glog.Infof("Request GetCorpTpAuthToken Response:(%s) %s", corpId, result)
	if nil != err {
		glog.Error(err)
		return "", err
	}

	response := lib.UnJson(result, new(WechatCorpTpAuthTokenResponse)).(*WechatCorpTpAuthTokenResponse)
	if nil == response || "" == response.AccessToken {
		return "", err
	}

	glog.Info("从腾讯服务器远程获取CorpAccessToken =========", response)
	gcache.SetIfNotExist(CorpAccessTokenCacheKey+corpId, response, time.Duration(response.ExpiresIn-1000)*time.Second)
	return response.AccessToken, nil
}

/**
wechatCorpTpTokenRequestor 获取第三方应用凭证（suite_access_token）
第三方应用的token	以suite_id（第三方应用ID）、suite_secret（第三方应用密钥）换取suite_access_token，代表第三方应用的身份	用于获取第三方应用的预授权码，获取授权企业信息等。说明文档参考 获取第三方应用凭证
说明：https://work.weixin.qq.com/api/doc/90001/90143/90600
*/
var wechatCorpTpTokenURL = "https://qyapi.weixin.qq.com/cgi-bin/service/get_suite_token"

func (p *Provider) RefreshSuiteToken(ticket string) {

	suiteAccessToken, err := gcache.Get(SuiteAccessTokenCacheKey + p.Config.SuiteId)
	if suiteAccessToken != nil {
		return
	}

	data := map[string]string{
		"suite_id":     p.Config.SuiteId,
		"suite_secret": p.Config.SuiteSecret,
		"suite_ticket": ticket}

	result, err := lib.HttpPostData(wechatCorpTpTokenURL, data)
	glog.Debugf("Request RefreshSuiteToken Response:SuiteId(%s) %s", p.Config.SuiteId, result)
	if nil != err {
		glog.Error(err)
		return
	}

	response := lib.UnJson(result, new(SuiteTokenRespons)).(*SuiteTokenRespons)
	if response == nil || "" == response.SuiteAccessToken {
		glog.Error("Request RefreshSuiteToken Failed: " + result)
		return
	}

	glog.Info("从腾讯服务器远程获取suite_access_token =========", response)
	gcache.SetIfNotExist(SuiteAccessTokenCacheKey+p.Config.SuiteId, response, time.Duration(response.ExpiresIn-1000)*time.Second)

	return
}

//getSuiteToken 从缓存中获取suite_access_token
func (p *Provider) getSuiteToken() string {
	suiteAccessTokenData, err := gcache.Get(SuiteAccessTokenCacheKey + p.Config.SuiteId)
	if err != nil {
		glog.Error(err)
		return ""
	}

	if suiteAccessTokenData != nil {
		sat := suiteAccessTokenData.(*SuiteTokenRespons)
		return sat.SuiteAccessToken
	}
	return ""
}

//设置Ticket到缓存
func (p *Provider) SetTicket(ticket string) {
	gcache.Set(TicketCacheKey+p.Config.SuiteId, ticket, 0)
}

//从缓存中取出Ticket
func (p *Provider) GetTicket() string {
	ticket, err := gcache.Get(TicketCacheKey + p.Config.SuiteId)
	if err != nil {
		glog.Error(err)
		return ""
	}
	return ticket.(string)
}
